'''
Author: Hugo
Date: 2022-02-28 10:01:06
LastEditTime: 2022-03-28 10:00:53
LastEditors: Please set LastEditors
Description: 画图
'''

# import datapane as dp

import pandas as pd

import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from typing import (List, Tuple, Union, Dict)


def plot_bar(df2show: pd.DataFrame,
             sel_col: str,
             ascending: bool = False,
             title: str = ''):
    """plot bar

    Parameters
    ----------
    df2show : pd.DataFrame
        index-概念名称 columns-n日涨幅
    sel_col : str
        选择n日涨幅
    ascending : bool, optional
        True按升序排列,False按降序排列 , by default False
    title : str, optional
        图标标题, by default ''

    Returns
    -------
    _type_
        可视化的图标
    """
    ser: pd.Series = df2show[sel_col].sort_values(ascending=ascending)
    colors = ['crimson' if i >= 0 else 'green' for _, i in ser.items()]

    fig = go.Figure(data=[
        go.Bar(
            x=ser.index.tolist(),
            y=ser.tolist(),
            marker_color=
            colors,  # marker color can be a single color value or an iterable
            hovertemplate='<i>动量</i>: %{y:.2%}' +
            '<br><b>所属行业</b>:%{x}%{_xother}</br><extra></extra>')
    ])
    fig.update_layout(title_text=title)

    return fig


def plot_bignum(name: str, v1: float, v2: float):

    if v2 > 0:
        is_upward_change, is_positive_intent = True, False
    else:
        is_upward_change, is_positive_intent = False, True

    return dp.BigNumber(heading=name,
                        value='{:.2}'.format(v1),
                        change='{:.2%}'.format(v2),
                        is_upward_change=is_upward_change,
                        is_positive_intent=is_positive_intent)


def plot_boston(df: pd.DataFrame):
    """画波士顿图

    Args:
        df (pd.DataFrame): index-行业名称,column-x,y

    Returns:
        _type_: _description_
    """
    fig = px.scatter(
        df,
        x="ROE_AVG",
        y="YOY_OR",
        color=df.index.tolist(),
        labels={"color": "行业名称"},
    )

    # 设置x轴，y轴
    fig.update_xaxes(showgrid=False,
                     zeroline=True,
                     zerolinecolor='black',
                     showticklabels=False,
                     zerolinewidth=0.5,
                     title='ROE')
    fig.update_yaxes(showgrid=False,
                     zeroline=True,
                     zerolinecolor='black',
                     showticklabels=False,
                     zerolinewidth=0.5,
                     title='营收增长率')

    fig.update_layout(showlegend=False,
                      width=800,
                      height=500,
                      title={
                          'text': "行业四象限",
                          'x': 0.5,
                          'xanchor': 'center',
                          'yanchor': 'top'
                      })

    fig.add_annotation(text="导入",
                       xref="paper",
                       yref="paper",
                       x=0.03,
                       y=0.95,
                       showarrow=False,
                       font_size=15,
                       font_color='red')

    fig.add_annotation(text="成长",
                       xref="paper",
                       yref="paper",
                       x=0.95,
                       y=0.95,
                       showarrow=False,
                       font_size=15,
                       font_color='red')

    fig.add_annotation(text="衰退",
                       xref="paper",
                       yref="paper",
                       x=0.03,
                       y=0.03,
                       showarrow=False,
                       font_size=15,
                       font_color='red')

    fig.add_annotation(text="成熟",
                       xref="paper",
                       yref="paper",
                       x=0.95,
                       y=0.03,
                       showarrow=False,
                       font_size=15,
                       font_color='red')

    return fig


def plot_dumbbell(df: pd.DataFrame, value_name: Tuple, title: str,
                  legend_name: str, width: int, height: int):
    """绘制杠铃图

    Parameters
    ----------
    df : pd.DataFrame
        index-y轴的标签 columns为杠铃两端的数据

    value_name : Tuple
        杠铃两端的名称 
    title : str
        标题名称
    legend_name : str
        图例名称
    width : int
        宽度
    height : int
        长度
    """
    x2, x1 = value_name

    fig = go.Figure()

    fig.add_trace(
        go.Scatter(
            x=df[x1].tolist(),
            y=df.index.tolist(),

            # 设置交互显示
            marker=dict(symbol='line-ns', line=dict(width=2, color='crimson')),
            hovertemplate='<i>百分位数</i>:%{x:.2%}' +
            '<br><b>所属行业</b>:%{y}%{_xother}</br>',
            mode="markers",
            hoverlabel=dict(bgcolor="crimson"),
            name=x1))

    fig.add_trace(
        go.Scatter(
            x=df[x2].tolist(),
            y=df.index.tolist(),
            hovertemplate='<i>百分位数</i>:%{x:.2%}' +
            '<br><b>所属行业</b>:%{y}%{_xother}</br>',
            marker=dict(symbol='line-ns', line=dict(width=2, color='blue')),
            hoverlabel=dict(bgcolor="blue"),
            mode="markers",
            name=x2,
        ))

    # 设置x轴，y轴
    fig.update_xaxes(showgrid=False,
                     zeroline=False,
                     linecolor='black',
                     mirror=True,
                     showticklabels=False)
    fig.update_yaxes(showgrid=False,
                     zeroline=False,
                     linecolor='black',
                     mirror=True)

    fig.update_layout(
        title={
            'text': title,
            'x': 0.5,
            'xanchor': 'center',
            'yanchor': 'top'
        },
        xaxis_title="PE百分位数",
        yaxis_title="行业名称",
        width=800,
        height=1500,
        legend_title_text=legend_name,
    )

    for i in range(df.shape[0]):

        x_a, x_b = df[x1].iloc[i], df[x2].iloc[i]
        label = df.index[i]
        # if x_a >= x_b:
        #     color = 'LightPink'
        # else:
        #     color = 'CadetBlue'
        fig.add_shape(
            type='line',
            layer="below",
            x0=x_a,
            y0=label,
            x1=x_b,
            y1=label,
            line_color="#cccccc",
        )

    return fig


def plot_heatmap(df2show: pd.DataFrame, title: str = ''):
    """plot heatmap

    Parameters
    ----------
    df2show : pd.DataFrame
        index-date columns-概念名称
    title : str, optional
        标题, by default ''

    Returns
    -------
    _type_
        _description_
    """
    fig = px.imshow(df2show,
                    color_continuous_scale='RdBu_r',
                    origin='lower',
                    labels=dict(x='概念名称', y='日期', color="动量得分"))

    fig.update_layout(yaxis_tickformat='%Y-%m-%d',
                      title_text=title,
                      coloraxis_colorbar=dict(tickformat='.2'))
    return fig


def plot_treemap(pct_chg: pd.DataFrame, weight_name: str, value_name: str,
                 path_name: List, title: str):
    """个股热度图

    Parameters
    ----------
    pct_chg : pd.DataFrame
        _description_
    weight_name : str
        大小的字段名
    value_name : str
        值的字段名
    path_name : List
        如何分级
    title : str
        标题

    Returns
    -------
    树图
    """
    fig = px.treemap(
        pct_chg,
        path=[px.Constant("热度")] + path_name,
        color=value_name,
        values=pct_chg[weight_name].abs(),
        hover_data={
            value_name: ':.2%',
            weight_name: ':.2f',
        },
        color_continuous_scale=px.colors.diverging.RdBu[::-1],
        color_continuous_midpoint=0,
    )

    fig.update_layout(margin=dict(t=50, l=25, r=25, b=25),
                      title={
                          'text': title,
                          'x': 0.5
                      },
                      coloraxis_colorbar=dict(tickformat='.2%'))
    return fig